package com.lilong.jwt.common.aop;

import com.alibaba.fastjson.JSONObject;
import com.google.common.base.Stopwatch;
import com.google.common.collect.Lists;
import com.lilong.jwt.common.exception.HydrauException;
import com.lilong.jwt.common.util.ResultBean;
import com.lilong.jwt.common.util.ResultUtil;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.security.authentication.BadCredentialsException;
import org.springframework.security.core.AuthenticationException;
import org.springframework.stereotype.Component;

import java.util.concurrent.TimeUnit;

/**
 * 用于处理请求日志记录及处理接口统一反回封装
 */
@Component
@Aspect
public class ControllerAspect {
    public static final Logger logger = LoggerFactory.getLogger(ControllerAspect.class);

    @Around("execution(public com.lilong.jwt.common.util.ResultBean com.hydrau.weixing.controller..*.*(..))")
    public Object handleControllerMethod(ProceedingJoinPoint pjp) {
        Stopwatch stopwatch = Stopwatch.createStarted();

        ResultBean resultEntity;
        try {
            logger.info("执行Controller开始: " + pjp.getSignature() + " 参数：" + Lists.newArrayList(pjp.getArgs()).toString());
            resultEntity = (ResultBean) pjp.proceed(pjp.getArgs());
            logger.info("执行Controller结束: " + pjp.getSignature() + "， 返回值：" + resultEntity.toString());
            logger.info("耗时：" + stopwatch.stop().elapsed(TimeUnit.MILLISECONDS) + "(毫秒).");
        } catch (Throwable throwable) {
            resultEntity = handlerException(pjp, throwable);
        }

        return resultEntity;
    }


    @Around(value = "execution(public org.springframework.http.ResponseEntity org.springframework.boot.autoconfigure.web.BasicErrorController.error(..))")
    public Object doAfterReturningAdvice1(ProceedingJoinPoint pjp) {
        try {
            ResponseEntity resultEntity = (ResponseEntity) pjp.proceed(pjp.getArgs());
            if (resultEntity.getBody() instanceof ResultBean) {
                return resultEntity;
            } else {
                JSONObject jo= (JSONObject) JSONObject.toJSON(resultEntity.getBody());
                return ResponseEntity.badRequest().body(ResultUtil.ERROR(resultEntity.getStatusCode().value(),jo.getString("message")));
            }
        } catch (Throwable throwable) {
            throwable.printStackTrace();
            return ResultUtil.ERROR(HttpStatus.BAD_REQUEST.value(), throwable.getMessage());
        }
    }

    private ResultBean handlerException(ProceedingJoinPoint pjp, Throwable e) {
        ResultBean resultEntity = new ResultBean();
        e.printStackTrace();
        if (e instanceof HydrauException) {
            logger.error("RuntimeException{方法：" + pjp.getSignature() + "， 参数：" + pjp.getArgs() + ",异常：" + e.getMessage() + "}", e);
           resultEntity=ResultUtil.ERROR((HydrauException) e);
        } else if (e instanceof BadCredentialsException) {//用户名或密码错误
            resultEntity.setMessage("用户名或密码错误!");
            resultEntity.setCode(HttpStatus.BAD_REQUEST.value());
        } else if (e instanceof AuthenticationException) {
            resultEntity.setMessage(e.getMessage());
            resultEntity.setCode(HttpStatus.BAD_REQUEST.value());
        } else {
            logger.error("异常{方法：" + pjp.getSignature() + "， 参数：" + pjp.getArgs() + ",异常：" + e.getMessage() + "}", e);
            resultEntity.setMessage(e.getMessage());
            resultEntity.setCode(HttpStatus.BAD_REQUEST.value());
        }
        return resultEntity;
    }

    public static void main(String[] args) {
        System.out.println(System.currentTimeMillis());
    }
}
